package com.leo.tool.guava;

import static org.junit.Assert.assertEquals;

import java.util.HashSet;
import java.util.List;
import java.util.stream.Stream;

import com.google.common.collect.*;
import org.junit.Test;

public class GuavaCollections {

    /**
     * HashMultiSet TreeMultiset LinkedHashMultiset ConcurrentHashMultiset ImmutableMultiset
     */
    @Test
    public void multiset() {
        Multiset<Object> multiset = HashMultiset.create();
        Stream.of("A", "B", "A", "C", "D", "A", "E").forEach(multiset::add);
        assertEquals(3, multiset.count("A"));
    }

    /**
     * HashMultimap ArrayListMultimap LinkedListMultimap LinkedHashMultimap TreeMultimap ImmutableMultiset
     * ImmutableListMultimap ImmutableSetMultimap
     */
    @Test
    public void multmap() {
        Multimap<String, Integer> multimap = HashMultimap.create();
        multimap.put("A", 1);
        multimap.put("B", 1);
        multimap.put("A", 2);
        multimap.put("A", 1);
        assertEquals(2, multimap.get("A").size());
    }

    /**
     * 双向映射（一一映射） HashBiMap ImmutableMap
     */
    @Test
    public void bimap() {
        HashBiMap<String, Integer> biMap = HashBiMap.create();
        biMap.put("A", 90);
        assertEquals(90, biMap.get("A").intValue());
        assertEquals("A", biMap.inverse().get(90));
    }

    /**
     * 工具类 Collections2 Lists Sets Maps Queues Multisets Multimaps Maps Tables
     */
    @Test
    public void sets() {
        HashSet<Integer> set1 = Sets.newHashSet(1, 2, 3, 4, 5);
        HashSet<Integer> set2 = Sets.newHashSet(3, 4, 5, 6, 7);
        assertEquals(Sets.newHashSet(1, 2, 3, 4, 5, 6, 7), Sets.union(set1, set2));// 并集
        assertEquals(Sets.newHashSet(3, 4, 5), Sets.intersection(set1, set2));// 交集
        assertEquals(Sets.newHashSet(1, 2), Sets.difference(set1, set2));// 补集
        assertEquals(Sets.newHashSet(6, 7), Sets.difference(set2, set1));// 补集
        assertEquals(Sets.newHashSet(1, 2, 6, 7), Sets.symmetricDifference(set1, set2));// 差集
    }

    /**
     * 笛卡尔乘积
     */
    @Test
    public void cartesianProduct() {
        List<List<Integer>> lists = Lists.newArrayList(
                Lists.newArrayList(10),
                Lists.newArrayList(20),
                Lists.newArrayList(30, 31, 32),
                Lists.newArrayList(4),
                Lists.newArrayList(51, 52)
        );
        List<List<Integer>> result = Lists.cartesianProduct(lists);
        assertEquals("[" +
                "[10, 20, 30, 4, 51], " +
                "[10, 20, 30, 4, 52], " +
                "[10, 20, 31, 4, 51], " +
                "[10, 20, 31, 4, 52], " +
                "[10, 20, 32, 4, 51], " +
                "[10, 20, 32, 4, 52]" +
                "]", result.toString());
    }

}
